package org.visionlibrary.image.filters.clustering.proto.model;

import java.util.ArrayList;
import java.util.List;

public class HSVCluster extends Cluster<Sample> {
	public HSVCluster(Sample centroid) {
		super(centroid);
	}

	@Override
	public void recalculate() {
		double hijsum = 0;
		double sisum = 0;
		double visumc = 0;
		double visumg = 0;
		
		List<Sample> color = new ArrayList<Sample>();
		List<Sample> gray = new ArrayList<Sample>();
		for(Sample sample : samples) {
			if(sample instanceof GraySample)
				gray.add(sample);
			else
				color.add(sample);
		}
		
		for(Sample c : color) {
			hijsum += relativeHue(c.getHue());
			sisum += c.getSat();
			visumc += c.getVal();
		}
		
		for(Sample g : gray) {
			visumg += g.getVal();
		}
		
		int hj = (int)Math.floor(hijsum / color.size());
		int sj = (int)Math.floor(sisum / (color.size() + gray.size()));
		int vj = (int)Math.floor((visumc + visumg) / (color.size() + gray.size()));
		
		int max = (int) Math.ceil(360/Sample.hQ);
		if(hj < 0) {
			hj = max + (hj%max);
		} else if(hj > max) {
			hj = 0 + (hj%max);
		}
		
		if(0 == vj || 0 == sj)
			this.centroid = new GraySample(vj);
		else
			this.centroid = new ColorSample(hj, sj, vj);
	}
	
	private double relativeHue(double hi) {
		int hj = centroid.getHue();
		if(Math.abs(hi - hj) > (180/Sample.hQ) && hj < (180/Sample.hQ))
			return hi - (360/Sample.hQ);
		
		if(Math.abs(hi - hj) > (180/Sample.hQ) && hj > (180/Sample.hQ))
			return hi + (360/Sample.hQ);
		
		return hi;
	}
}
